/*
 * sprite.c
 *
 *  Created on: 2010/05/20
 *      Author: angela
 */

#include "sprite.h"
#include "compat.h"
#include <stdlib.h>

char * read_xpm(char * map[], int * wd, int * ht)
{
  __attribute__((unused)) static char read_xpm_jcard;

  int width, height, colors;
  char sym[256];
  int  col;
  int i, j;
  char *pix, *pixtmp, *tmp, *line;
  char symbol;

  width = strtol( map[0] , &tmp , 10 );
  height = strtol ( tmp , &tmp , 10 );
  colors = strtol ( tmp , NULL , 10 );
  if (width > HRES || height > VRES || colors > 256) 
  {
    return NULL;
  }

  *wd = width;
  *ht = height;

  for (i=0; i<256; i++)
    sym[i] = 0;

  // read symbols <-> colors
  for (i=0; i<colors; i++) 
  {/*
    if (sscanf(map[i+1], "%c %d", &symbol, &col) != 2) 
    {
      return NULL;
    }*/
	symbol = map[i+1][0];
	col = strtol( map[i+1]+1 , &tmp , 10 );

    if (col > 256) 
    {
      return NULL;
    }
    sym[col] = symbol;
  }

  // allocate pixmap memory
  pix = pixtmp = malloc(width*height);

  // parse each pixmap symbol line
  for (i=0; i<height; i++) 
  {
    line = map[colors+1+i];
    for (j=0; j<width; j++) 
    {
      tmp = memchr(sym, line[j], 256);  // find color of each symbol
      if (tmp == NULL) 
      {
        return NULL;
      }
      *pixtmp++ = tmp - sym; // pointer arithmetic! back to books :-)
    }
  }
  
  return pix;
}

Sprite* create_sprite(char * pic[], char * base)
{
    int wd, ht;
    char* spr = read_xpm(pic, &wd, &ht);
    Sprite* s = (Sprite *) malloc (sizeof(Sprite));

    if (s == NULL) return NULL;

    if ((s->map = spr) == NULL)
    {
        free(s);
        return NULL;
    }

    s->x = 0; 
    s->y = 0;
    s->width = wd; 
    s->height = ht;
    s->map = spr;
    
    return s;
}


void delete_sprite( Sprite * sprt, char * base)
{
    char *dSprt=sprt->map;
    int i,k;
    
    for(i=0;i<sprt->height;i++)
    {        
        for(k=0;k<sprt->width;k++)
        {
            if(*dSprt == get_pixel(sprt->x+k,sprt->y+i,base)) //verificar se o que se esta na posicao é mesmo o que pretendemos apagar
                set_pixel(sprt->x+k,sprt->y+i, 0 ,base);
            dSprt++;
        }
    }
}

void destroy_sprite( Sprite * sprt, char * base)
{
    if (sprt == NULL)
        return;

    delete_sprite(sprt, base);

    free(sprt->map);
    free(sprt);
    sprt = NULL;
}

void draw_sprite(Sprite * sprt, char * base)
{
    char * Sprt = sprt->map;
    int i,k;

    for(i=0;i<sprt->height;i++)
    {
        for(k=0;k<sprt->width;k++)
         {
            if(*Sprt != 0)
                set_pixel(sprt->x+k,sprt->y+i, *Sprt ,base);
            Sprt++;
         }
    }
}
